package com.qqtech.qquan.user.service;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.qqtech.core.common.enums.YesNoEnum;
import com.qqtech.core.common.util.StringUtil;
import com.qqtech.core.common.util.TimeUtil;
import com.qqtech.core.frame.dao.BaseDao;
import com.qqtech.core.frame.model.PageKit;
import com.qqtech.core.frame.model.PageOrder;
import com.qqtech.core.frame.model.Result;
import com.qqtech.core.frame.service.BaseServiceImpl;
import com.qqtech.qquan.circle.service.CircleMemberService;
import com.qqtech.qquan.community.service.CommunityJoinService;
import com.qqtech.qquan.coupon.enums.CouponBaseBizzTypeDictEnum;
import com.qqtech.qquan.coupon.enums.CouponUserObtainWayDictEnum;
import com.qqtech.qquan.coupon.model.CouponBaseVo;
import com.qqtech.qquan.coupon.service.CouponBaseService;
import com.qqtech.qquan.coupon.service.CouponUserService;
import com.qqtech.qquan.draw.enums.UserDrawStatusDictEnum;
import com.qqtech.qquan.draw.model.DrawBaseQuery;
import com.qqtech.qquan.draw.model.DrawBaseVo;
import com.qqtech.qquan.draw.model.DrawBatchQuery;
import com.qqtech.qquan.draw.model.DrawBatchVo;
import com.qqtech.qquan.draw.model.DrawItemVo;
import com.qqtech.qquan.draw.service.DrawBaseService;
import com.qqtech.qquan.draw.service.DrawBatchService;
import com.qqtech.qquan.draw.service.DrawItemService;
import com.qqtech.qquan.mall.enums.MallConst;
import com.qqtech.qquan.mall.enums.MallSupplierTypeDictEnum;
import com.qqtech.qquan.mall.model.MallProductSpecVo;
import com.qqtech.qquan.mall.model.MallProductVo;
import com.qqtech.qquan.mall.model.MallShopVo;
import com.qqtech.qquan.mall.model.MallSupplier;
import com.qqtech.qquan.mall.service.MallProductService;
import com.qqtech.qquan.mall.service.MallProductSpecService;
import com.qqtech.qquan.mall.service.MallShopService;
import com.qqtech.qquan.mall.service.MallSupplierService;
import com.qqtech.qquan.user.dao.UserDrawDao;
import com.qqtech.qquan.user.enums.UserDrawTypeDictEnum;
import com.qqtech.qquan.user.model.UserDraw;
import com.qqtech.qquan.user.model.UserDrawQuery;
import com.qqtech.qquan.user.model.UserDrawVo;

import jersey.repackaged.com.google.common.collect.Lists;

@Service
public class UserDrawServiceImpl extends BaseServiceImpl<UserDraw> implements UserDrawService {
	public static final Logger log = LoggerFactory.getLogger(UserDrawServiceImpl.class);

	@Resource
	private UserDrawDao userDrawDao;

	@Resource
	private DrawItemService drawItemService;

	@Resource
	private DrawBatchService drawBatchService;

	@Resource
	private DrawBaseService drawBaseService;

	@Resource
	private CouponUserService couponUserService;

	@Resource
	private CouponBaseService couponBaseService;

	@Resource
	private UserValueService userValueService;

	@Resource
	private MallProductService mallProductService;

	@Resource
	private MallShopService mallShopService;

	@Resource
	private MallProductSpecService mallProductSpecService;

	@Resource
	private MallSupplierService mallSupplierService;

	@Resource
	private UserDrawService userDrawService;

	@Resource
	private CircleMemberService circleMemberService;

	@Resource
	private CommunityJoinService communityJoinService;

	@Override
	protected BaseDao<UserDraw> getBaseDao() {
		return userDrawDao;
	}

	@Override
	public List<UserDrawVo> queryList4Draw(UserDrawQuery userDrawQuery, Pageable pageable) {
		return userDrawDao.queryList4Draw(userDrawQuery, pageable);
	}

	@Override
	public Result addUserDraw(Integer userId, Integer type, Integer bizzId, Integer drawBaseId) {
		Result result = new Result();
		String hours = drawBaseService.getDrawHours();
		if (type == UserDrawTypeDictEnum.SHARE.getCode()) {
			int updateCount = userValueService.updateMinusDrawCount(userId);
			if (updateCount <= 0) {
				result.addErr("亲，您的分享次数已经使用了。");
				return result;
			}
		} else {
			if (type == UserDrawTypeDictEnum.CIRCLE.getCode()) {
				boolean isCircleMember = circleMemberService.isCircleMember(userId, bizzId);
				if (!isCircleMember) {
					result.addErr("亲，您还不是该圈子成员。");
					return result;
				}
			} else if (type == UserDrawTypeDictEnum.COMMUNITY.getCode()) {
				boolean isJoinCommunity = communityJoinService.isJoinCommunity(bizzId, userId);
				if (!isJoinCommunity) {
					result.addErr("亲，请先加入该社区。");
					return result;
				}
			}
			UserDrawQuery userDrawQuery = new UserDrawQuery();
			userDrawQuery.setBizzId(bizzId);
			userDrawQuery.setType(type);
			userDrawQuery.setUserId(userId);
			userDrawQuery.setNow(TimeUtil.now());
			int count = userDrawDao.queryCount(userDrawQuery);
			if (count == 1) {
				if (type == UserDrawTypeDictEnum.CIRCLE.getCode()) {
					result.addErr("亲，您今天该圈子已经抽过奖了。");
				} else if (type == UserDrawTypeDictEnum.COMMUNITY.getCode()) {
					result.addErr("亲，您今天该社区已经抽过奖了。");
				}
				return result;
			}
			/*
			 * UserDrawQuery userDrawQuery = new UserDrawQuery();
			 * userDrawQuery.setBizzId(bizzId); userDrawQuery.setType(type);
			 * userDrawQuery.setUserId(userId);
			 * userDrawQuery.setNow(TimeUtil.now()); int count =
			 * userDrawDao.queryCount(userDrawQuery); if (count == 1) { if (type
			 * == UserDrawTypeDictEnum.CIRCLE.getCode()) {
			 * result.addErr("亲，您今天该圈子已经抽过奖了。"); } else {
			 * result.addErr("亲，您今天该社区已经抽过奖了。"); } return result; }
			 */
		}
		DrawBatchQuery drawBatchQuery = new DrawBatchQuery();
		drawBatchQuery.setDrawBaseId(drawBaseId);
		List<DrawBatchVo> items = drawBatchService.queryList(drawBatchQuery,
				new PageKit(new PageOrder(Direction.ASC, "id")));
		int i = 1;
		List<DrawBatchVo> itemListNew = Lists.newArrayList();//存放有余量的奖品（代金券）
		CouponBaseVo couponTemp = null;//临时（代金券）变量
		DrawItemVo drawItemTemp = null;//临时（抽奖奖品）变量
		for (DrawBatchVo drawBatchVo : items) {
			int rate = drawBatchVo.getRate();
			if (rate > 0) {
				drawBatchVo.setStartNum(i);
				drawBatchVo.setEndNum(i + rate - 1);
				i = i + rate;
			}
			/***过滤有余量的奖品begin****/
			if(drawBatchVo.getQuantity()>0 && rate >0){//筛选-抽奖批次里的奖品库存大于0,并且 中奖率大于0的
				drawItemTemp = drawItemService.getById(drawBatchVo.getDrawItemId());
				if(drawItemTemp!=null){
					couponTemp = couponBaseService.getById(drawItemTemp.getCouponId());
					if(couponTemp!=null && couponTemp.getQuantity()>0){
						itemListNew.add(drawBatchVo);//添加一个有余量的奖品（代金券）
					}
				}
			}
			/***过滤有余量的奖品end****/
		}
		if(itemListNew==null || itemListNew.size()==0){
			result.addErr("抱歉，所有奖品已被抽空。");
			return result;
		}
		DrawBatchVo drawBatchVo = addRandom(itemListNew);//在有余量的奖品池中，计算出一个抽中的奖品
		if(drawBatchVo==null){//为了防止抽不中奖品
			result.addErr("抱歉，所有奖品已被抽空。");
			return result;
		}
		int drawNum = -1;//中奖奖品号（下标: 0-5）
		//重新定位中奖号，因为筛选过的奖品池跟原先的不一样，所以得到的下标也不一样
		for (int k=0;k<items.size();k++) {
			if(items.get(k).getDrawItemId()==drawBatchVo.getDrawItemId()){
				drawNum = k;
				break;
			}
		}
		if(drawNum < 0){//定位不了中奖号
			result.addErr("抱歉，所有奖品已被抽空。");
			return result;
		}
		result.put("num", drawNum);

		UserDraw userDraw = new UserDraw();
		userDraw.setUserId(userId);
		userDraw.setDrawItemId(drawBatchVo.getDrawItemId());
		userDraw.setType(type);
		userDraw.setBizzId(bizzId);
		userDraw.setDrawBaseId(drawBaseId);
		DrawItemVo drawItemVo = drawItemService.getById(drawBatchVo.getDrawItemId());
		userDraw.setDrawItemName(drawItemVo.getName());
		if (StringUtil.isBlank(hours)) {
			hours = "";
		}
		userDraw.setHour(hours);
		userDraw.setStatus(UserDrawStatusDictEnum.RECEIVE.getCode());
		if (drawItemVo != null && drawItemVo.getCouponId() != null) {// 优惠卷
			int id = userDrawDao.insert(userDraw);
			CouponBaseVo couponBaseVo = couponBaseService.getById(drawItemVo.getCouponId());
			if (CouponBaseBizzTypeDictEnum.MALL_PRODUCT.getCode() == couponBaseVo.getBizzType()) {
				MallProductVo mallProduct = mallProductService.getById(couponBaseVo.getBizzId());
				MallShopVo mallShopVo = mallShopService.getById(mallProduct.getShopId());
				List<MallProductSpecVo> productSpecLst = mallProductSpecService
						.queryListByProductId(mallProduct.getId());
				mallProduct.setProductSpecLst(productSpecLst);
				mallProduct.setImgString(mallProduct.getImg(), MallConst.IMG_BIG);
				MallSupplier supplier = mallSupplierService.getById(mallProduct.getSupplierId());
				if (supplier != null) {
					mallProduct.setSupplierTypeCode(supplier.getType());
					mallProduct.setSupplierTypeStr(MallSupplierTypeDictEnum.getDesc(supplier.getType()));
				}
				result.put("mallShopVo", mallShopVo);
				result.put("mallProduct", mallProduct);
			}
			Integer couponUserId = couponUserService.addCouponUser(userId, drawItemVo.getCouponId(),
					CouponUserObtainWayDictEnum.DRAW, id);
			result.put("couponUserId", couponUserId);
		} else {
			userDrawDao.insert(userDraw);
		}
		result.put("drawItemVo", drawItemVo);
		return result;
	}

	private DrawBatchVo addRandom(List<DrawBatchVo> items) {
		int random = (int) (Math.random() * 1000);
		DrawBatchVo drawItemVo2 = null;
		for (int j = 0; j < items.size(); j++) {
			drawItemVo2 = items.get(j);
			if (null != drawItemVo2.getStartNum() && null != drawItemVo2.getEndNum()) {
				if (random > drawItemVo2.getStartNum() && random < drawItemVo2.getEndNum()) {
					drawItemVo2.setDrawNum(j);
					break;
				} else if (random == drawItemVo2.getStartNum()) {
					drawItemVo2.setDrawNum(j);
					break;
				} else if (random == drawItemVo2.getEndNum()) {
					drawItemVo2.setDrawNum(j);
					break;
				}
			}

		}
		if (null == drawItemVo2) {
			//drawItemVo2 = addRandom(items);//可能会死循环
			int index=(int)(Math.random()*items.size());//随机取数组中的一个下标
			drawItemVo2 = items.get(index);
			drawItemVo2.setDrawNum(index);
		}
		int updateCount = drawBatchService.updateMinusQuantity(drawItemVo2.getId());
		/* 可能会死循环
		if (updateCount <= 0) {
			drawItemVo2 = addRandom(items);
		}*/
		return drawItemVo2;
	}

	@Override
	public Page<UserDrawVo> queryPageListAdmin(UserDrawQuery query, Pageable pageable) {
		return userDrawDao.queryPageListAdmin(query, pageable);
	}

	@Override
	public boolean isDraw(Integer userId) {
		DrawBaseQuery drawBaseQuery = new DrawBaseQuery();
		drawBaseQuery.setNow(TimeUtil.now());
		drawBaseQuery.setStatus(YesNoEnum.YES.getCode());
		List<DrawBaseVo> list = drawBaseService.queryList(drawBaseQuery);
		if (null != list && list.size() > 0) {
			String chooseHour = drawBaseService.getDrawHours();
			if (StringUtil.isNotBlank(chooseHour)) {
				UserDrawQuery query = new UserDrawQuery();
				query.setUserId(userId);
				query.setNow(TimeUtil.now());
				query.setHour(chooseHour);
				int count = userDrawDao.queryCount(query);
				if (count <= 0) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isDraw(Integer userId, String hours) {
		if (StringUtil.isNotBlank(hours)) {
			UserDrawQuery query = new UserDrawQuery();
			query.setUserId(userId);
			query.setNow(TimeUtil.now());
			query.setHour(hours);
			int count = userDrawDao.queryCount(query);
			if (count <= 0) {
				return true;
			}
		}
		return false;
	}

}